﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Nolineq.Iterators
{
    /// <summary>
    /// Iterator metody bisekce.
    /// </summary>
    public class BisectionIterator : Iterator
    {
        public BisectionIterator(EquationSolver solver)
            : base(solver)
        { }

        /// <summary>
        /// Provede iteraci metody bisekce.
        /// </summary>
        /// <returns>Vrati TRUE, pokud se iterace provedla. Jinak vrati FALSE.</returns>
        public override bool Iterate()
        {
            double left = Solver.Start;
            double right = Solver.End;

            // nesplnena podminka pro iteraci
            if (Solver.Function.Evaluate(left) * Solver.Function.Evaluate(right) >= 0)
                throw new CannotIterateException("Nesplněna podmínka f(a) * f(b) < 0. Zadejte jiný interval nebo zvolte jinou metodu.");

            // vypocet stredu
            double mid = (left + right) / 2;

            // zkontrolujeme, jestli mame koren
            if (Math.Abs(Solver.Function.Evaluate(mid)) < Solver.Precision)
            {
                Solver.Approximation = mid;
                return false;
            }

            // rozhodne se, jestli vezmeme levy nebo pravy interval
            if (Solver.Function.Evaluate(mid) * Solver.Function.Evaluate(left) < 0)
                right = mid;
            else
                left = mid;

            // pouzijeme referenci a upravime hodnoty intervalu a aproximace
            Solver.Start = left;
            Solver.End = right;
            Solver.Approximation = mid;

            // provedli jsme iteraci -> vratime true
            return true;
        }
    }
}
